From e6d394a2d74c1d42b3a7ea3a783c219c4710cd25 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 9 Jun 2015 19:31:47 -0700 Subject: [PATCH] Fix propagation of build script args It looks like the recent restructuring into an O(N) pass had a regression (reported in #1695) where deps-of-deps didn't have their build script arguments propagated upwards. This fixes the caching logic to take into account the profile as part of the key to ensure that we traverse targets twice if necessary. Closes #1695 --- src/cargo/ops/cargo_rustc/context.rs | 4 +- src/cargo/ops/cargo_rustc/custom_build.rs | 25 +++++----- src/cargo/ops/cargo_rustc/mod.rs | 14 ++---- tests/test_cargo_compile_custom_build.rs | 56 +++++++++++++++++++++++ 4 files changed, 76 insertions(+), 23 deletions(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 4a1284074..642942722 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -36,8 +36,8 @@ pub struct Context<'a, 'cfg: 'a> { Fingerprint>, pub compiled: HashSet<(&'a PackageId, &'a Target, &'a Profile)>, pub build_config: BuildConfig, - pub build_scripts: HashMap<(&'a PackageId, Kind), - Vec<(&'a PackageId, Profile)>>, + pub build_scripts: HashMap<(&'a PackageId, Kind, &'a Profile), + Vec<&'a PackageId>>, host: Layout, target: Option, diff --git a/src/cargo/ops/cargo_rustc/custom_build.rs b/src/cargo/ops/cargo_rustc/custom_build.rs index be426396b..3e3cea9fe 100644 --- a/src/cargo/ops/cargo_rustc/custom_build.rs +++ b/src/cargo/ops/cargo_rustc/custom_build.rs @@ -347,7 +347,8 @@ impl BuildOutput { /// /// The given set of targets to this function is the initial set of /// targets/profiles which are being built. -pub fn build_map(cx: &mut Context, targets: &[(&Target, &Profile)]) { +pub fn build_map<'b, 'cfg>(cx: &mut Context<'b, 'cfg>, + targets: &[(&Target, &'b Profile)]) { let mut ret = HashMap::new(); let pkg = cx.get_package(cx.resolve.root()); for &(target, profile) in targets { @@ -356,32 +357,32 @@ pub fn build_map(cx: &mut Context, targets: &[(&Target, &Profile)]) { } // Make the output a little more deterministic by sorting all dependencies - for (&(id, kind), slot) in ret.iter_mut() { - slot.sort_by(|&(p1, _), &(p2, _)| p1.cmp(p2)); + for (&(id, kind, _), slot) in ret.iter_mut() { + slot.sort(); slot.dedup(); debug!("script deps: {}/{:?} => {:?}", id, kind, - slot.iter().map(|&(s, _)| s.to_string()).collect::>()); + slot.iter().map(|s| s.to_string()).collect::>()); } cx.build_scripts = ret; // Recursive function to build up the map we're constructing. This function // memoizes all of its return values as it goes along. - fn build<'a, 'b, 'cfg>(out: &'a mut HashMap<(&'b PackageId, Kind), - Vec<(&'b PackageId, Profile)>>, + fn build<'a, 'b, 'cfg>(out: &'a mut HashMap<(&'b PackageId, Kind, &'b Profile), + Vec<&'b PackageId>>, kind: Kind, pkg: &'b Package, target: &Target, - profile: &Profile, + profile: &'b Profile, cx: &Context<'b, 'cfg>) - -> &'a [(&'b PackageId, Profile)] { + -> &'a [&'b PackageId] { // If this target has crossed into "host-land" we need to change the // kind that we're compiling for, and otherwise just do a quick // pre-flight check to see if we've already calculated the set of // dependencies. let kind = if target.for_host() {Kind::Host} else {kind}; let id = pkg.package_id(); - if out.contains_key(&(id, kind)) { - return &out[&(id, kind)] + if out.contains_key(&(id, kind, profile)) { + return &out[&(id, kind, profile)] } // This loop is both the recursive and additive portion of this @@ -409,13 +410,13 @@ pub fn build_map(cx: &mut Context, targets: &[(&Target, &Profile)]) { if target.linkable() && kind == dep_kind { if pkg.has_custom_build() { - ret.push((pkg.package_id(), profile.clone())); + ret.push(pkg.package_id()); } ret.extend(dep_scripts.iter().cloned()); } } - let prev = out.entry((id, kind)).or_insert(Vec::new()); + let prev = out.entry((id, kind, profile)).or_insert(Vec::new()); prev.extend(ret); return prev } diff --git a/src/cargo/ops/cargo_rustc/mod.rs b/src/cargo/ops/cargo_rustc/mod.rs index 162930be9..ee8c95a1e 100644 --- a/src/cargo/ops/cargo_rustc/mod.rs +++ b/src/cargo/ops/cargo_rustc/mod.rs @@ -451,16 +451,12 @@ fn rustc(package: &Package, target: &Target, profile: &Profile, } } -fn load_build_deps(cx: &Context, pkg: &Package, profile: &Profile, - kind: Kind) -> Vec { +fn load_build_deps(cx: &Context, pkg: &Package, + profile: &Profile, kind: Kind) -> Vec { let pkg = cx.get_package(pkg.package_id()); - let deps = match cx.build_scripts.get(&(pkg.package_id(), kind)) { - Some(a) => a, - None => return Vec::new(), - }; - deps.iter().filter(|&&(_, ref dep_profile)| profile == dep_profile) - .map(|&(x, _)| x.clone()) - .collect() + cx.build_scripts.get(&(pkg.package_id(), kind, profile)).map(|deps| { + deps.iter().map(|&d| d.clone()).collect::>() + }).unwrap_or(Vec::new()) } // For all plugin dependencies, add their -L paths (now calculated and diff --git a/tests/test_cargo_compile_custom_build.rs b/tests/test_cargo_compile_custom_build.rs index 6a2996400..1125dd444 100644 --- a/tests/test_cargo_compile_custom_build.rs +++ b/tests/test_cargo_compile_custom_build.rs @@ -1300,3 +1300,59 @@ test!(cfg_override { assert_that(p.cargo_process("build").arg("-v"), execs().with_status(0)); }); + +test!(flags_go_into_tests { + let p = project("foo") + .file("Cargo.toml", r#" + [project] + name = "foo" + version = "0.5.0" + authors = [] + + [dependencies] + b = { path = "b" } + "#) + .file("src/lib.rs", "") + .file("tests/foo.rs", "") + .file("b/Cargo.toml", r#" + [project] + name = "b" + version = "0.5.0" + authors = [] + [dependencies] + a = { path = "../a" } + "#) + .file("b/src/lib.rs", "") + .file("a/Cargo.toml", r#" + [project] + name = "a" + version = "0.5.0" + authors = [] + build = "build.rs" + "#) + .file("a/src/lib.rs", "") + .file("a/build.rs", r#" + fn main() { + println!("cargo:rustc-link-search=test"); + } + "#); + + assert_that(p.cargo_process("test").arg("-v").arg("--test=foo"), + execs().with_status(0).with_stdout(&format!("\ +{compiling} a v0.5.0 ([..] +{running} `rustc a[..]build.rs [..]` +{running} `[..]build-script-build[..]` +{running} `rustc a[..]src[..]lib.rs [..] -L test[..]` +{compiling} b v0.5.0 ([..] +{running} `rustc b[..]src[..]lib.rs [..] -L test[..]` +{compiling} foo v0.5.0 ([..] +{running} `rustc src[..]lib.rs [..] -L test[..]` +{running} `rustc tests[..]foo.rs [..] -L test[..]` +{running} `[..]foo-[..]` + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured + +", compiling = COMPILING, running = RUNNING))); +}); -- 2.30.2